
#include "rtmp_resource.h"
#include "rtmp_connection.h"
#include "rtmp_message.h"
#include <memory>
#include <spdlog/fmt/bundled/format-inl.h>
#include <string>

bool RtmpConnectionCompare(std::shared_ptr<RtmpConnection> & a, std::shared_ptr<RtmpConnection> & b)
{
    return a->Index() != b->Index();
}

RtmpMediaResource::RtmpMediaResource()
{
}

RtmpMediaResource::~RtmpMediaResource()
{
    TRACE("release rtmp media resource");
}

void RtmpMediaResource::UpdateStream(const std::string & stream)
{
    m_stream = stream;
}

void RtmpMediaResource::ProcessMessage(std::shared_ptr<RtmpConnection> conn, std::shared_ptr<RtmpMessage> & msg)
{

}

void RtmpMediaResource::BroadcastMsg(std::shared_ptr<RtmpMessage> msg)
{
	TRACE("pull media stream conn size : {}", m_pull_conn_set.size());
    for (auto & conn : m_pull_conn_set)
    {
        conn->SendRespMsg(msg);
    }
}

void RtmpMediaResource::TakePushConn(std::shared_ptr<RtmpConnection> conn)
{
    m_push_conn = conn;
}

void RtmpMediaResource::AddPullConn(std::shared_ptr<RtmpConnection> conn)
{
    m_pull_conn_set.insert(conn);
}

bool RtmpMediaResource::CheckPushConn(std::shared_ptr<RtmpConnection> conn)
{
    if (!m_push_conn || !conn)
    {
        return false;
    }
    bool result = !RtmpConnectionCompare(conn, m_push_conn);
    return result;
}

void RtmpMediaResource::RemoveConn(std::shared_ptr<RtmpConnection> conn)
{
    if (conn)
    {
        if (m_push_conn && m_push_conn->Index() == conn->Index())
        {
            m_push_conn = nullptr;
        }
        else
        {
			INFO("remove pull stream connection : {}", conn->Index());
            m_pull_conn_set.erase(conn);
        }
        if (!m_push_conn && m_pull_conn_set.empty())
        {
            RtmpMediaResourceMgr::Instance()->RemoveResource(m_stream);
        }
    }
}

void RtmpMediaResource::SaveMetadData(std::shared_ptr<RtmpMessage> & msg)
{
    m_meta_data = msg;
}

RtmpMediaResourceMgr::RtmpMediaResourceMgr()
{

}

std::shared_ptr<RtmpMediaResource> RtmpMediaResourceMgr::Source(const std::string & stream)
{
    auto iter = m_media_source_map.find(stream);
    if (iter == m_media_source_map.end())
    {
        auto resource = std::make_shared<RtmpMediaResource>();

        resource->UpdateStream(stream);

        m_media_source_map[stream] = resource;

        return resource;
    }
    return iter->second;
}

void RtmpMediaResourceMgr::RemoveResource(const std::string & stream)
{
    m_media_source_map.erase(stream);
}

